<template>
  <view class="content">
    <view class="header">
      <text class="title">Concentration Calculation</text>
    </view>

    <view class="calculator-container">
      <view class="card" v-if="hasFormula">
        <view class="formula-display">
          <text class="formula-title"
            >Current Formula ({{ getBestChannelName() }} Channel)</text
          >
          <text
            v-if="formula && formula.regressionType === 'linear'"
            class="formula"
            >(S₀-S)/S₀ = {{ formula.slope.toFixed(7) }} × Conc. +
            {{ formula.intercept.toFixed(7) }}</text
          >
          <text
            v-else-if="
              formula &&
              formula.regressionType === 'poly' &&
              formula.coefficients &&
              formula.coefficients.length >= 3
            "
            class="formula"
            >(S₀-S)/S₀ = {{ formula.coefficients[0].toFixed(7) }} × Conc.² +
            {{ formula.coefficients[1].toFixed(7) }} × Conc. +
            {{ formula.coefficients[2].toFixed(7) }}</text
          >
          <text v-else class="formula">No formula available</text>
          <text v-if="formula" class="formula-accuracy"
            >Accuracy: R² = {{ formula.rSquared.toFixed(7) }}</text
          >
          <text v-if="formula" class="formula-type"
            >Regression Type:
            {{
              formula.regressionType === "linear" ? "Linear" : "Polynomial"
            }}</text
          >
        </view>

        <view class="input-section">
          <text class="section-title">Enter RGB Value</text>
          <view class="input-row">
            <input
              type="number"
              v-model="rgbInput.r"
              placeholder="R Value"
              :class="{ 'active-input': formula.channel === 'r' }"
            />
            <input
              type="number"
              v-model="rgbInput.g"
              placeholder="G Value"
              :class="{ 'active-input': formula.channel === 'g' }"
            />
            <input
              type="number"
              v-model="rgbInput.b"
              placeholder="B Value"
              :class="{ 'active-input': formula.channel === 'b' }"
            />
          </view>
          <text class="input-hint"
            >您可以输入任意通道的RGB值进行计算。当前优选通道为 {{ formula.channel.toUpperCase() }}，推荐优先使用该通道获得更准确结果。</text
          >

          <button @click="calculateFromButton" type="primary">
            Calculate Concentration
          </button>
        </view>

        <view class="result-section" v-if="result !== null">
          <text class="result-title">Calculation Result</text>
          <text class="result-value">{{ result.toFixed(4) }} μM</text>
          <view class="result-formula">
            <text>Process:</text>
            <text>1. (S₀-S)/S₀ = {{ getCalculationProcess() }}</text>
            <text>2. Concentration = {{ getCalculationFormula() }}</text>
          </view>
        </view>
      </view>

      <view class="empty-card" v-else>
        <text class="empty-title">No Calculation Formula Available</text>
        <text class="empty-desc">Please perform data analysis first to generate a calculation formula.</text>
        <button @click="goToAnalysis" type="primary">Go to Data Analysis</button>
      </view>

      <view class="color-preview" v-if="hasValidRgbInput || (formula && formula.channel)">
        <text class="preview-title">Current RGB Preview</text>
        <view
          class="color-box"
          :style="{
            backgroundColor: `rgb(${previewRgbComputed.r}, ${previewRgbComputed.g}, ${
              previewRgbComputed.b
            })`,
          }"
        ></view>
        <text class="color-code"
          >RGB({{ previewRgbComputed.r }}, {{ previewRgbComputed.g }},
          {{ previewRgbComputed.b }})</text
        >
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      formula: null,
      rgbInput: {
        r: "",
        g: "",
        b: "",
      },
      result: null,
      calcProcess: null,
      s0Reference: null,
    };
  },
  watch: {
    'rgbInput.r': function(newVal) {
      if (newVal !== "") {
        this.calculateConcentration('r');
      }
    },
    'rgbInput.g': function(newVal) {
      if (newVal !== "") {
        this.calculateConcentration('g');
      }
    },
    'rgbInput.b': function(newVal) {
      if (newVal !== "") {
        this.calculateConcentration('b');
      }
    }
  },
  computed: {
    hasFormula() {
      return this.formula !== null;
    },
    hasValidRgbInput() {
      return this.rgbInput.r !== "" || this.rgbInput.g !== "" || this.rgbInput.b !== "";
    },
    previewRgbComputed() {
      let r = 0, g = 0, b = 0;
      
      if (this.hasValidRgbInput) {
        // 优先使用用户输入的值
        r = this.rgbInput.r !== "" ? Number(this.rgbInput.r) || 0 : (this.s0Reference ? this.s0Reference.r : 0);
        g = this.rgbInput.g !== "" ? Number(this.rgbInput.g) || 0 : (this.s0Reference ? this.s0Reference.g : 0);
        b = this.rgbInput.b !== "" ? Number(this.rgbInput.b) || 0 : (this.s0Reference ? this.s0Reference.b : 0);
      } else if (this.s0Reference) {
        // 如果没有用户输入，使用参考值
        r = this.s0Reference.r || 0;
        g = this.s0Reference.g || 0;
        b = this.s0Reference.b || 0;
      }
      
      // 确保值在0-255范围内
      r = Math.min(255, Math.max(0, r));
      g = Math.min(255, Math.max(0, g));
      b = Math.min(255, Math.max(0, b));
      
      return { r, g, b };
    }
  },
  onLoad() {
    this.loadFormulaAndS0();
  },
  methods: {
    loadFormulaAndS0() {
      try {
        const formulaData = uni.getStorageSync("bestFormula");
        if (formulaData) {
          this.formula = JSON.parse(formulaData);
          console.log("Formula loaded successfully:", this.formula);
          this.fetchS0Reference(); 
        } else {
          console.log("No formula data found.");
        }
      } catch (e) {
        console.error("Failed to load formula:", e);
      }
    },
    fetchS0Reference(){
        try {
            const completeData = uni.getStorageSync("completeData");
            if (completeData) {
                const dataPoints = JSON.parse(completeData);
                if (dataPoints && dataPoints.length > 0) {
                    const sortedData = [...dataPoints].sort(
                        (a, b) => a.concentration - b.concentration
                    );
                    this.s0Reference = sortedData[0];
                    console.log("S0 Reference point loaded:", this.s0Reference);
                } else {
                    console.log("No data points found to determine S0 reference.");
                    this.s0Reference = null;
                }
            } else {
                 console.log("Complete data not found for S0 reference.");
                 this.s0Reference = null;
            }
        } catch(e) {
            console.error("Failed to load S0 reference data:", e);
            this.s0Reference = null;
        }
    },
    getBestChannelName() {
      if (!this.formula) return "";
      const channelMap = {
        r: "R (Red)",
        g: "G (Green)",
        b: "B (Blue)",
      };
      return channelMap[this.formula.channel];
    },
    calculateFromButton() {
      if (!this.formula) {
        return;
      }
      
      // 检查各通道输入情况
      const hasRedInput = this.rgbInput.r !== "";
      const hasGreenInput = this.rgbInput.g !== "";
      const hasBlueInput = this.rgbInput.b !== "";
      
      // 如果有多个通道输入，优先使用推荐的通道
      if (hasRedInput && this.formula.channel === 'r') {
        this.calculateConcentration('r');
      } else if (hasGreenInput && this.formula.channel === 'g') {
        this.calculateConcentration('g');
      } else if (hasBlueInput && this.formula.channel === 'b') {
        this.calculateConcentration('b');
      } 
      // 如果没有推荐通道的输入，使用任意有输入的通道
      else if (hasRedInput) {
        this.calculateConcentration('r');
      } else if (hasGreenInput) {
        this.calculateConcentration('g');
      } else if (hasBlueInput) {
        this.calculateConcentration('b');
      } else {
        // 没有任何输入
        uni.showToast({
          title: "请至少输入一个RGB通道值",
          icon: "none"
        });
      }
    },
    calculateConcentration(channel) {
      if (!this.formula) {
        return;
      }
      
      // 如果没有明确指定通道，使用优选通道
      const activeChannel = channel || this.formula.channel;
      const inputValue = this.rgbInput[activeChannel];
      
      if (inputValue === "") {
        this.result = null;
        this.calcProcess = null; 
        return;
      }
      const value = Number(inputValue);
      if (isNaN(value)) {
        this.result = null; 
        this.calcProcess = null;
        return; 
      }

      const s0Point = this.s0Reference; 

      if (!s0Point || s0Point[activeChannel] === undefined) {
          console.error("S0 reference point or its channel value is undefined. S0:", s0Point, "Channel:", activeChannel);
          this.fetchS0Reference(); 
          if (!this.s0Reference || this.s0Reference[activeChannel] === undefined) {
            uni.showToast({
                title: "S₀ reference data is incomplete or missing.",
                icon: "none",
            });
            this.result = null;
            this.calcProcess = null;
            return;
          }
          const freshS0Point = this.s0Reference;
          const s0Value = freshS0Point[activeChannel];
          this.proceedWithCalculation(value, s0Value, activeChannel);
          return;
      }
      
      const s0Value = s0Point[activeChannel];
      this.proceedWithCalculation(value, s0Value, activeChannel);
    },

    proceedWithCalculation(currentValue, s0Val, channel) {
        let sRatio = 0;
        if (s0Val !== 0) {
          sRatio = (s0Val - currentValue) / s0Val;
        }
        this.calcProcess = `(${s0Val} - ${currentValue}) / ${s0Val} = ${sRatio.toFixed(7)}`;
        
        if (this.formula.regressionType === "linear") {
          const { slope, intercept } = this.formula;
          if (slope === 0) {
             uni.showToast({
              title: "Slope is zero, cannot calculate concentration reliably.",
              icon: "none",
            });
            this.result = null; 
            return;
          }
          this.result = (sRatio - intercept) / slope;
        } else if (this.formula.regressionType === "poly") {
          const coeffs = this.formula.coefficients;
          const a = coeffs[0];
          const b = coeffs[1];
          const c = coeffs[2] - sRatio;
          if (a === 0) { 
            if (b === 0) {
                uni.showToast({
                    title: "Polynomial coefficients (a, b) are zero, cannot calculate concentration.",
                    icon: "none",
                });
                this.result = null;
                return;
            }
            this.result = -c / b;
          } else {
            const discriminant = b * b - 4 * a * c;
            if (discriminant < 0) {
              uni.showToast({
                title: "No real solution for concentration (discriminant < 0).",
                icon: "none",
              });
              this.result = null;
              return;
            }
            const sol1 = (-b + Math.sqrt(discriminant)) / (2 * a);
            const sol2 = (-b - Math.sqrt(discriminant)) / (2 * a);
            this.result = Math.max(sol1, sol2); 
            if (this.result < 0 && (sol1 >=0 || sol2 >=0) ) { 
                 this.result = Math.min(sol1, sol2) > 0 ? Math.min(sol1,sol2) : Math.max(sol1, sol2); 
            }
          }
        }
    },

    getCalculationProcess() {
      return this.calcProcess || "N/A";
    },
    getCalculationFormula() {
      if (!this.result || !this.formula || !this.calcProcess) return "N/A";
      const sRatioText = this.calcProcess.split("=")[1];
      if (!sRatioText) return "Error in process string";
      const sRatio = parseFloat(sRatioText.trim());

      if (this.formula.regressionType === "linear") {
        return `(${sRatio.toFixed(7)} - ${this.formula.intercept.toFixed(
          7
        )}) / ${this.formula.slope.toFixed(7)}`;
      } else if (this.formula.regressionType === "poly") {
        const a = this.formula.coefficients[0];
        const b = this.formula.coefficients[1];
        const c_prime = this.formula.coefficients[2] - sRatio;
        if (a === 0) {
            return `(${-c_prime.toFixed(7)}) / ${b.toFixed(7)}`;
        }
        return `Quadratic: (-${b.toFixed(7)} ± sqrt(${b.toFixed(7)}² - 4*${a.toFixed(7)}*${c_prime.toFixed(7)})) / (2*${a.toFixed(7)})`;
      }
      return "N/A";
    },
    goToAnalysis() {
      uni.navigateTo({
        url: "/pages/analysis/analysis",
      });
    },
  },
};
</script>

<style>
.content {
  padding: 20rpx;
}

.header {
  text-align: center;
  margin-bottom: 30rpx;
}

.title {
  font-size: 40rpx;
  font-weight: bold;
  color: #333;
}

.calculator-container {
  margin-bottom: 40rpx;
}

.card {
  background-color: #fff;
  border-radius: 15rpx;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
  padding: 30rpx;
  margin-bottom: 30rpx;
}

.formula-display {
  background-color: #f0f7ff;
  padding: 20rpx;
  border-radius: 10rpx;
  margin-bottom: 20rpx;
}

.formula-title {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 10rpx;
  display: block;
}

.formula {
  font-size: 32rpx;
  color: #333;
  margin-bottom: 10rpx;
  display: block;
}

.formula-accuracy {
  font-size: 24rpx;
  color: #666;
  display: block;
}

.formula-type {
  font-size: 24rpx;
  color: #666;
  display: block;
}

.input-section {
  margin-bottom: 30rpx;
}

.section-title {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 15rpx;
  display: block;
}

.input-row {
  display: flex;
  gap: 15rpx;
  margin-bottom: 10rpx;
}

.input-row input {
  flex: 1;
  height: 70rpx;
  border: 1px solid #ddd;
  border-radius: 10rpx;
  padding: 0 15rpx;
  background-color: #f9f9f9;
}

.active-input {
  border: 2px solid #007aff !important;
  background-color: #fff !important;
}

.input-hint {
  font-size: 24rpx;
  color: #999;
  margin-bottom: 20rpx;
  display: block;
}

.result-section {
  background-color: #f5f5f5;
  padding: 20rpx;
  border-radius: 10rpx;
}

.result-title {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 10rpx;
  display: block;
}

.result-value {
  font-size: 48rpx;
  font-weight: bold;
  color: #007aff;
  margin-bottom: 15rpx;
  display: block;
  text-align: center;
}

.result-formula {
  font-size: 24rpx;
  color: #666;
}

.empty-card {
  background-color: #f5f5f5;
  padding: 40rpx;
  border-radius: 15rpx;
  text-align: center;
  margin-bottom: 30rpx;
}

.empty-title {
  font-size: 32rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 15rpx;
  display: block;
}

.empty-desc {
  font-size: 28rpx;
  color: #666;
  margin-bottom: 30rpx;
  display: block;
}

.color-preview {
  background-color: #fff;
  border-radius: 15rpx;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
  padding: 30rpx;
  text-align: center;
}

.preview-title {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 20rpx;
  display: block;
}

.color-box {
  width: 150rpx;
  height: 150rpx;
  border-radius: 15rpx;
  border: 1px solid #ddd;
  margin: 0 auto 20rpx;
}

.color-code {
  font-size: 28rpx;
  color: #666;
}
</style>
